﻿using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using XCI.Helper;
using XCI.Windows.Helper;
using XCI.Windows.Plugin.GridSetting;

namespace XCI.Sys.Helper
{
    public static class AppHelper
    {
        /// <summary>
        /// 启动应用程序
        /// </summary>
        /// <param name="args">启动参数</param>
        public static void Run<T>(params string[] args) where T : IApp, new()
        {
            var app = new T();
            #region 读取应用信息
            try
            {
                SysRuntime.App = app;                   // 当前应用程序对象
                SysRuntime.Setting = app.GetSetting();  // 应用程序设置
                SysRuntime.StartupArgs = args;          // 启动参数
                SysRuntime.SplashScreenType = app.GetSplashScreen();

                SplashHelper.RegisterSplash(SysRuntime.SplashScreenType);
                SplashHelper.ShowSplash("正在启动...");

                SysRuntime.WaitFormType = app.GetWaitForm();
                SplashHelper.RegisterWait(SysRuntime.WaitFormType);
                SysRuntime.Api = app.GetApi(SysRuntime.Setting);

                Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = new CultureInfo("zh-Hans");
                Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
                //处理UI线程异常
                Application.ThreadException += (s, e) =>
                {
                    SysRuntime.App.GlobalExceptionProcess(e.Exception);
                };
                //处理非UI线程异常
                AppDomain.CurrentDomain.UnhandledException += (s, e) =>
                {
                    SysRuntime.App.GlobalExceptionProcess(e.ExceptionObject as Exception);
                };
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "系统启动异常", MessageBoxButtons.OK,
                                MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                return;
            }
            #endregion

            SplashHelper.ShowSplash("正在加载插件...");
            Windows.Controls.GridPager.DefaultPageSize = SysRuntime.Setting.PageSize;
            Windows.Controls.GridPager.DefaultPageSizeList = SysRuntime.Setting.PageSizeList;
            GridSettingManager.Register(app.GetGridSetting());
            DXImageHelper.Init();
            WinHelper.RegisterSkin(ThemeSetting.GetThemeSetting());

            Action main = () =>
            {
                SplashHelper.ShowSplash("正在初始化系统...");
                SysRuntime.MainForm = app.GetMainForm(); // 主窗口
                SysRuntime.Setting.AllowGridSetting = SysRuntime.IsAuthorize("sys.allowGridSetting");
                SysRuntime.App.OnLoginSuccess();
                Application.Run(SysRuntime.MainForm);
            };

            Action execute = () =>
            {
                if (!string.IsNullOrEmpty(SysRuntime.Setting.ApiUrl))
                {
                    SplashHelper.ShowSplash("正在连接服务器...");
                    if (!app.Ping())
                    {
                        SplashHelper.CloseSplash();
                        MessageBox.Show("无法连接到服务器,请联系系统管理员!", "系统提示", MessageBoxButtons.OK,
                            MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                        return;
                    }
                }

                if (SysRuntime.Setting.EnableSyncDate)
                {
                    SplashHelper.ShowSplash("正在同步时间...");
                    SyncDate syncDate = new SyncDate(SysRuntime.Api)
                    {
                        MessageCallback = SplashHelper.ShowSplash
                    };
                    syncDate.Sync();

                    //30分钟
                    TimerHelper.TimerExecute("syncDate", 1000 * 60 * 30, () => { new SyncDate(SysRuntime.Api).Sync(); });
                }

                if (SysRuntime.Setting.EnableUpdate)
                {
                    SplashHelper.ShowSplash("正在检查系统更新...");
                    Upd upd = new Upd()
                    {
                        MessageCallback = SplashHelper.ShowSplash
                    };
                    upd.StartUpdate();
                }

                SysRuntime.LoginForm = app.GetLoginForm(); // 登陆窗口
                if (SysRuntime.LoginForm != null)
                {
                    SplashHelper.CloseSplash();
                    if (SysRuntime.LoginForm.ShowDialog() == DialogResult.OK)
                    {
                        main();
                    }
                }
                else
                {
                    main();
                }
            };

            if (SysRuntime.Setting.IsSingleton)
            {
                Mutex mutex = new Mutex(true, SysRuntime.Setting.Id, out bool hasMutex);
                if (hasMutex)
                {
                    execute();
                    mutex.ReleaseMutex();
                }
                else
                {
                    SplashHelper.CloseSplash();
                    MessageBox.Show("已经有一个客户端程序在运行了,一台计算机上不能同时运行多个客户端", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                    Environment.Exit(0);
                }
            }
            else
            {
                execute();
            }
        }

        /// <summary>
        /// 重启应用程序
        /// </summary>
        public static void RestartApplication(params string[] args)
        {
            var param = string.Join(" ", args);
            var processId = Process.GetCurrentProcess().Id;
            var startupPath = Application.ExecutablePath;
            try
            {
                Process.Start("daemon.exe", $"restart {processId} {startupPath} {param}");
            }
            catch (FileNotFoundException)
            {
                throw new SystemException("找不到守护进程文件:daemon.exe");
            }
            catch (Exception)
            {
                throw new SystemException("守护进程启动失败");
            }

            //Process.Start(Application.ExecutablePath, String.Format("-restart {0} {1}", Process.GetCurrentProcess().Id,
            //paramString));
            //Environment.Exit(0);
        }

        /// <summary>
        /// 重新登陆应用程序
        /// </summary>
        public static void ReLoginApplication()
        {
            RestartApplication("switch");
        }

        /// <summary>
        /// 当前是否重登录状态
        /// </summary>
        /// <param name="args">启动参数</param>
        public static bool IsReLogin(string[] args)
        {
            return args != null && args.Any(p => p.Equals("switch"));
        }

        /// <summary>
        /// 杀死应用程序
        /// </summary>
        public static void KillApplication()
        {
            var processId = Process.GetCurrentProcess().Id;
            //var startupPath = Application.ExecutablePath;
            try
            {
                Process.Start("daemon.exe", $"kill {processId}");
            }
            catch (FileNotFoundException)
            {
                throw new SystemException("找不到守护进程文件:daemon.exe");
            }
            catch (Exception)
            {
                throw new SystemException("守护进程启动失败");
            }
        }

        /// <summary>
        /// 退出应用程序
        /// </summary>
        public static void ExitApplication()
        {
            Environment.Exit(0);
        }
    }
}
